package com.gt.quality.job.core;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronExpression;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;

import java.time.Instant;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;

/**
 * 万里悲秋常作客,百年多病独登台
 *
 * @author : makeJava
 */
@Component
@Slf4j
public class DynamicTaskService {

    @Autowired
    private ThreadPoolTaskScheduler taskScheduler;

    /**
     * 、
     * 存储任务Future的Map
     */
    private final Map<String, ScheduledFuture<?>> scheduledTasks = new ConcurrentHashMap<>();

    /**
     * 添加一个新的定时任务||更新已存在的定时任务
     *
     * @param taskId         任务ID
     * @param cronExpression cron表达式
     * @param task           任务
     */
    public void addOrUpdateCronTask(String taskId, String cronExpression, Runnable task) {
        log.info("加载定时任务----Id--{}||表达式---->{}", taskId, cronExpression);
        // 验证cronExpression是否有效
        if (taskId == null || taskId.trim().isEmpty()) {
            throw new IllegalArgumentException("任务ID不能为空");
        }
        try {
            cronExpression = convertQuartzToSpringBootCron(cronExpression);
            // 检查cron表达式的合法性
            if (!CronExpression.isValidExpression(cronExpression)) {
                throw new IllegalArgumentException("无效的cron表达式: " + cronExpression);
            }
        } catch (Exception e) {
            throw new IllegalArgumentException("cron表达式错误: " + e.getMessage(), e);
        }

        // 如果任务已存在，先移除
        if (scheduledTasks.containsKey(taskId)) {
            boolean cancelTask = cancelTask(taskId);
            log.info("取消任务----Id--{},取消状态-----{}", taskId, cancelTask);
        }

        // 创建触发器
        CronTrigger trigger = new CronTrigger(cronExpression);
        // 调度任务并保存future
        ScheduledFuture<?> future = taskScheduler.schedule(task, trigger);
        scheduledTasks.put(taskId, future);

    }

    /**
     * 转换 Quartz Cron 表达式为 Spring Boot Cron 表达式
     *
     * @param quartzCron Quartz Cron 表达式
     * @return Spring Boot Cron 表达式
     */
    public static String convertQuartzToSpringBootCron(String quartzCron) {
        // 将 Quartz Cron 表达式按照空格分割成数组
        String[] quartzCronParts = quartzCron.trim().split(" ");

        // 如果 Quartz Cron 表达式有 7 个字段，去掉第一个字段 (年字段)
        if (quartzCronParts.length == 7) {
            // 删除年字段，并返回前六个字段作为 Spring Boot Cron 表达式
            return String.join(" ", quartzCronParts[0], quartzCronParts[1], quartzCronParts[2], quartzCronParts[3], quartzCronParts[4], quartzCronParts[5]);
        }

        // 如果是 Spring Boot 格式的 6 字段 Cron 表达式，直接返回
        if (quartzCronParts.length == 6) {
            return String.join(" ", quartzCronParts);
        }

        // 如果格式不符合标准，抛出异常
        throw new IllegalArgumentException("Invalid Cron expression format.");
    }

    /**
     * 取消任务
     *
     * @param taskId 任务id
     * @return boolean
     */
    public boolean cancelTask(String taskId) {
        ScheduledFuture<?> future = scheduledTasks.get(taskId);
        if (future != null) {
            boolean cancelled = future.cancel(true);
            if (cancelled) {
                scheduledTasks.remove(taskId);
            }
            return cancelled;
        }
        return false;
    }

    /**
     * 获取所有任务ID
     *
     * @return Set<String>
     */
    public Set<String> getAllTaskIds() {
        return scheduledTasks.keySet();
    }

    /**
     * 延迟执行
     */
    public void lazyLoadingTask(Date delayedStartTime, Runnable taskRunner) {
        // 设置任务执行的时间点
        Instant startTime = delayedStartTime.toInstant();
        taskScheduler.schedule(taskRunner, startTime);
    }
}
